package calao.storage;

import calao.util.Arrays;

public abstract class DataReader 
{
	
	public class ObsoleteBindingException extends RuntimeException 
	{
		ObsoleteBindingException(DataBinding binding, int requiredVersion)
		{
			super("Data binding "+binding.name+" version "+requiredVersion+"+ required");
		}
	}

	Object context;
	
	abstract public int readInt();
	abstract public long readLong();
	abstract public double readDouble();
	abstract public String readString();
	abstract public boolean readBoolean();

	public int[] readIntArray()
	{
		int[] result = new int[readInt()];
		for (int i=0; i<result.length; i++) result[i] = readInt();
		return result;
	}

	@SuppressWarnings("unchecked")
	public <T> T[] readObjectArray(Class<T> type) 
	throws UnknownBindingException
	{
		T[] result = Arrays.newArray(type, readInt());
		for (int i=0; i<result.length; i++) result[i] = (T)readObject();
		return result;		
	}

	/** Reads data binding name.
	 * @return The binding currently registered for that name.
	 */
	protected DataBinding readBindingName()
	throws UnknownBindingException
	{
		return DataBinding.getBinding(readString());	
	}

	protected int readBindingVersion()
	{
		return readInt();	
	}

	public Object readObject()
	throws UnknownBindingException
	{
		if (readBoolean()) {
			DataBinding binding = readBindingName();
			int version = readBindingVersion();
			if (version>binding.version) {
				throw new ObsoleteBindingException(binding, version);
			}
			return binding.readObject(this, version);
		}
		return null;
	}
	
	public void setContext(Object object)
	{
		this.context = object;
	}
	
	public Object getContext()
	{
		return context;
	}

}
